#!/usr/bin/perl

use strict;
use warnings;

# tell Perl where to find MozComics package
BEGIN { push @INC, "/home/mozcomic/scrapers/"; }

use MozComics::JSON;
use MozComics::MySQL;

use LWP::Simple;
use DateTime;
use DateTime::Format::Strptime;
use HTML::Entities qw(decode_entities);

BEGIN {
	# comic updated on Mon, Wed, Fri
	my $todaysWday = DateTime->now()->wday;
	if($todaysWday != 1 and $todaysWday != 3 and $todaysWday != 5) {
		exit;
	}
}

my $guid = 'ce382245-943c-4a06-a62d-b93ef377fb66';

#my $comic = MozComics::JSON->new($guid);
my $comic = MozComics::MySQL->new($guid);
my $comicName = $comic->getName();
my $urlPrefix = 'http://www.penny-arcade.com/comic';
my $escapedUrlPrefix = quotemeta($urlPrefix);

my $lastStripRow = $comic->getLastStrip();

my $dateParser = new DateTime::Format::Strptime(
	pattern => '%Y/%m/%d',
	locale  => 'en_US'
);

sub getNextDate {
	my $date = shift(@_) or die "$comicName: date not passed to getNextDate";
	$date->add(days => 2);
	if($date->wday == 7) {
		$date->add(days => 1);
	}
}

sub parseDateFromUrl {
	my $url = shift(@_) or die "$comicName: url not passed to parseDateFromUrl";
	$url =~ /^$escapedUrlPrefix\/([\d\/]+?)\/$/
	        or die "$comicName: malformed url in parseDateFromUrl";
	my $dateString = $1;

	return $dateParser->parse_datetime($dateString)
	       or die "$comicName: could not parse date ($dateString)";
}

# scrape information from a page
sub scrapePage {
	my $url = shift(@_) or die "$comicName: url not passed to scrapePage";
	my $page = shift(@_) or die "$comicName: page not passed to scrapePage";
	my @scrapedStrips;
	my $strip = parseDateFromUrl($url)->epoch();
	my $foundStrips = 0;

	while($page =~ /\<div class="post comic"\>\s*<img src="(.+?)" alt="(.+?)" \/\>\s*\<\/div\>/gs) {
		$strip += 1000;
		$foundStrips++;

		push @scrapedStrips, {
			strip => $strip,
			url => $url,
			image => $1,
			title => decode_entities($2),
		};
	}


	if($foundStrips == 0) {
		die "$comicName: did not find any strips on $url";
	}
	elsif($foundStrips > 1) {
		#print "$url\n";
		die "$comicName: found more than one strip on $url";
	}

	return @scrapedStrips;
}


my $stripPage = get($lastStripRow->{url})
                or die "$comicName: last page url not found";
my @scrapedStrips = scrapePage($lastStripRow->{url}, $stripPage);
my $lastStripData = $scrapedStrips[0];
$comic->assertStripsEqual($lastStripData, $lastStripRow);

my $date = parseDateFromUrl($lastStripRow->{url});
my $now = DateTime->now();
my $end = DateTime->new(year => $now->year, month => $now->month, day => $now->day);

my @urls;
for(getNextDate($date); DateTime->compare($date, $end)<1; getNextDate($date)) {
	my $dateString = $dateParser->format_datetime($date);
	push @urls, "$urlPrefix/$dateString/";
}

my $lastStripImage = $lastStripData->{image};
for my $url (@urls) {
	$stripPage = get($url) or next;
	@scrapedStrips = scrapePage($url, $stripPage);

	for my $scrapedStrip (@scrapedStrips) {
		# if first image scraped is same as the image from lastStripData,
		# no new strips have been found (just repeats from last strip)
		if($scrapedStrip->{image} eq $lastStripImage) {
			next;
		}
		$lastStripImage = $scrapedStrip->{image};

		$comic->addStrip($scrapedStrip);
	}
}

$comic->commit();

